package kr.co.bettersoft.waitnumbercustomer.activity;

import static kr.co.bettersoft.waitnumbercustomer.common.CommonConstant.SENDER_ID;

import kr.co.bettersoft.waitnumbercustomer.common.CommonConstant;
import kr.co.bettersoft.waitnumbercustomer.common.WaitNumberCustomerRest;
import kr.co.bettersoft.waitnumbercustomer.domain.MemberUser;

import org.json.JSONObject;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;

import com.google.android.gcm.GCMBaseIntentService;

import android.os.Vibrator;

import android.support.v4.app.NotificationCompat.Builder;

/**
 * GCMIntentService
 * 서버로부터 푸시 알림을 받기 위한 GCM 서비스 이다.
 * 
 * 어플 실행시 구글에 GCM 을 등록하고, GCM 아이디가 바꼈을 경우 서버에 업데이트 한다.
 * 서버로부터 푸시 알림을 받았을 경우 사용자에게 노티를 준다. 
 *
 */
public class GCMIntentService extends GCMBaseIntentService {
//////////////////////////////////////////////////////////////////////////////////////////////////////
// 변수	
	
	private static final String TAG = "GCMIntentService";
	public static String myQR = "";
	
	// 진동
	Vibrator Vi;	// 고객 순번 알림을 받으면 진동이 울리도록 하기 위함.
	int vibrateCnt = 3;

	// 서버 통신 관련
	Boolean dontTwice = true;
//	WaitNumberCustomerRest waitNumberCustomerRest = new WaitNumberCustomerRest();
//	String callResult = "";
//	String tempstr = "";
//	JSONObject jsonObject;
	
	// GCM
	String regIdGCM = "";
	Context localContext;
	String regResult="";


	// 설정 파일 저장소   -- 설정에 GCM ID 를 저장하여 GCM ID 가 변경된 경우에만 서버로 업데이트 한다.
	SharedPreferences sharedPrefCustom;
	String savedGCMId = "";

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	public GCMIntentService() {
		super(SENDER_ID);
	}

	/**
	 * onRegistered
	 *  gcm 등록되면 비동기로 서버에 업데이트한다
	 *
	 * @param context
	 * @param registrationId
	 * @return
	 */
	@Override
	public void onRegistered(Context context, String registrationId) {
		Vi= (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
		
		// prefs
		sharedPrefCustom = getSharedPreferences(CommonConstant.prefName,
				Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
		savedGCMId = sharedPrefCustom.getString("savedGCMId", "");	
		myQR = sharedPrefCustom.getString("qrCode", "");
		if(dontTwice){			// 한번 하고 막는다.
			regIdGCM = registrationId;
			
			// gcm 푸시 테스트 위해. 잠시 주석 처리. 항시 서버에 올리도록.
//			if(!(savedGCMId.equals(regIdGCM))){	// pref 에 저장된것(=서버에 저장된것)과 등록한 GCM 아이디가 다를때에만 업데이트 하도록 한다.		// *** 
				new backgroundThreadUpdateMyGCMtoServer().execute();	// 비동기로 전환 - 서버에 GCM 아이디 저장	 *** 
				//            displayMessage(context, getString(R.string.gcm_registered));			// 브로드 케스트로 보내줌.. 리시버가 잡음. (노티는 없음)
				localContext = context;
				dontTwice = false;
//			}else{
//				Log.d(TAG,"saved GCM Id is not changed.");
//				// *** 업뎃 하지 않음.
//			}
		}
	}

	/**
	 * GCM ID 를 pref 설정에 저장한다.
	 */
	public void saveGCMIdToPref(){
		SharedPreferences.Editor updatesavedGCMId =   sharedPrefCustom.edit();
		updatesavedGCMId.putString("savedGCMId", regIdGCM);		// GCM ID저장
		updatesavedGCMId.commit();
	}
	
	@Override
	protected void onUnregistered(Context context, String registrationId) {
		Log.i(TAG, "Device unregistered");
	}

	/**
	 * onMessage
	 *  서버에서 푸시가 오면 사용자에게 노티를 준다
	 *
	 * @param context
	 * @param intent
	 * @return
	 */
	@Override		// GCM 서비스 에서 온 메시지 받은거.
	protected void onMessage(Context context, Intent intent) {
		Log.i(TAG, "Received message");
		Vi= (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
		String message = intent.getStringExtra("MESSAGE");
		Log.i(TAG, "Received message of onMessage():"+intent.getStringExtra("MESSAGE"));		// 동작함.

		// notifies user
		generateNotification(context, message);	// 사용자에게 노티를 준닷

	}

	@Override
	protected void onDeletedMessages(Context context, int total) {
		Log.i(TAG, "Received deleted messages notification");
	}

	@Override
	public void onError(Context context, String errorId) {
		Log.i(TAG, "Received error: " + errorId);
	}

	@Override
	protected boolean onRecoverableError(Context context, String errorId) {
		// log message
		Log.i(TAG, "Received recoverable error: " + errorId);
		return super.onRecoverableError(context, errorId);
	}

	/**
	 * generateNotification
	 * Issues a notification to inform the user that server has sent a message.
	 * @param context
	 * @param message
	 * @return
	 */
	private  void generateNotification(Context context, String message) {
		int icon = R.drawable.ic_launcher;
		long when = System.currentTimeMillis();
		NotificationManager notificationManager = (NotificationManager)
		context.getSystemService(Context.NOTIFICATION_SERVICE);
		
		Notification notification ;
		if(message.equals("ADMISSION")){		// 처음 받자마자 상단에 뜨는 부분
			notification = new Notification(icon, getString(R.string.gcm_your_turn), when);
		}else if(message.equals("NEXT_TURN")){			 
			notification = new Notification(icon, getString(R.string.gcm_you_next_turn), when);
		}else if(message.equals("NEW_EVENT")){
			notification = new Notification(icon, getString(R.string.gcm_new_event), when);
		}else if(message.equals("REGISTER_WAITING")){	
			notification = new Notification(icon, getString(R.string.gcm_you_registered), when);
		}else if(message.equals("CANCEL")){	
			notification = new Notification(icon, getString(R.string.gcm_you_canceled), when);
		}else if(message.contains("ADDITIONAL_USER_TURN")){
			String showMsg = message.substring( ("ADDITIONAL_USER_TURN_").length() ) + getString(R.string.gcm_turns_left);		// "턴 전입니다."
			notification = new Notification(icon, showMsg, when);
		}else{
			notification = new Notification(icon, message, when);
		}
		
		String title = context.getString(R.string.app_name);
		Intent notificationIntent;

		/*
		 * ADMISSION -> 입장하시기 바랍니다.
		 * NEXT_TURN -> 다음차례입니다.
		 * NEW_EVENT -> 새로운 이벤트가 도착했습니다.
		 * REGISTER_WAITING -> 대기명단에 등록되었습니다.
		 */
		
		// 상단을 아래로 내려서 노티 확인할때 보여지는 부분
		if(message.equals("ADMISSION")){
			Log.d(TAG,"ADMISSION");
			vibrateNTimes();	
			
			notificationIntent = new Intent(context, DummyActivity.class);	
			notificationIntent.putExtra("RunMode", "ADMISSION");						 
//			// set intent so it does not start a new activity
			PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
			NotificationManager nm = (NotificationManager) context
			.getSystemService(Context.NOTIFICATION_SERVICE);
			Resources res = context.getResources();
			Builder builder = new Builder(context);
			builder.setContentIntent(contentIntent)
			.setSmallIcon(R.drawable.ic_launcher)
			.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
			.setTicker(res.getString(R.string.app_name))
			.setWhen(System.currentTimeMillis())
			.setAutoCancel(true)
			.setContentTitle(res.getString(R.string.app_name))
			.setContentText(getString(R.string.gcm_your_turn));
			Notification n = builder.build();
			nm.notify(0, n);
		}else if(message.equals("NEXT_TURN")){			
			vibrateOneTimes();
			Log.d(TAG,"NEXT_TURN");
			notificationIntent = new Intent(context, DummyActivity.class);	
			notificationIntent.putExtra("RunMode", "NEXT_TURN");						//
//			// set intent so it does not start a new activity
			PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
			NotificationManager nm = (NotificationManager) context
			.getSystemService(Context.NOTIFICATION_SERVICE);
			Resources res = context.getResources();
			Builder builder = new Builder(context);
			builder.setContentIntent(contentIntent)
			.setSmallIcon(R.drawable.ic_launcher)
			.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
			.setTicker(res.getString(R.string.app_name))
			.setWhen(System.currentTimeMillis())
			.setAutoCancel(true)
			.setContentTitle(res.getString(R.string.app_name))
			.setContentText(getString(R.string.gcm_you_next_turn));
			Notification n = builder.build();		// android-support-v13 에 있는 기능
			nm.notify(0, n);
		}else if(message.contains("ADDITIONAL_USER_TURN")){	
			vibrateOneTimes();
			Log.d(TAG,"ADDITIONAL_USER_TURN");
			notificationIntent = new Intent(context, DummyActivity.class);	
			notificationIntent.putExtra("RunMode", "NEXT_TURN");						//
//			// set intent so it does not start a new activity
			PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
			NotificationManager nm = (NotificationManager) context
			.getSystemService(Context.NOTIFICATION_SERVICE);
			Resources res = context.getResources();
			Builder builder = new Builder(context);
			builder.setContentIntent(contentIntent)
			.setSmallIcon(R.drawable.ic_launcher)
			.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
			.setTicker(res.getString(R.string.app_name))
			.setWhen(System.currentTimeMillis())
			.setAutoCancel(true)
			.setContentTitle(res.getString(R.string.app_name))
			.setContentText(getString(R.string.gcm_you_next_turn));
			Notification n = builder.build();		// android-support-v13 에 있는 기능
			nm.notify(0, n);
		}else if(message.equals("NEW_EVENT")){
			Log.d(TAG,"NEW_EVENT");
			vibrateOneTimes();
			notificationIntent = new Intent(context, DummyActivity.class);	
			notificationIntent.putExtra("RunMode", "NEW_EVENT");						//
			PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
			NotificationManager nm = (NotificationManager) context
			.getSystemService(Context.NOTIFICATION_SERVICE);
			Resources res = context.getResources();
			Builder builder = new Builder(context);
			builder.setContentIntent(contentIntent)
			.setSmallIcon(R.drawable.ic_launcher)
			.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
			.setTicker(res.getString(R.string.app_name))
			.setWhen(System.currentTimeMillis())
			.setAutoCancel(true)
			.setContentTitle(res.getString(R.string.app_name))
			.setContentText(getString(R.string.gcm_new_event));
			Notification n = builder.build();
			nm.notify(0, n);
		}else if(message.equals("REGISTER_WAITING")){						
			Log.d(TAG,"REGISTER_WAITING");
			vibrateOneTimes();
			notificationIntent = new Intent(context, DummyActivity.class);	
			notificationIntent.putExtra("RunMode", "REGISTER_WAITING");						//
			PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
			NotificationManager nm = (NotificationManager) context
			.getSystemService(Context.NOTIFICATION_SERVICE);
			Resources res = context.getResources();
			Builder builder = new Builder(context);
			builder.setContentIntent(contentIntent)
			.setSmallIcon(R.drawable.ic_launcher)
			.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
			.setTicker(res.getString(R.string.app_name))
			.setWhen(System.currentTimeMillis())
			.setAutoCancel(true)
			.setContentTitle(res.getString(R.string.app_name))
			.setContentText(getString(R.string.gcm_you_registered));
			Notification n = builder.build();
			nm.notify(0, n);
		}else if(message.equals("CANCEL")){						
			Log.d(TAG,"CANCEL_WAITING");
			vibrateOneTimes();
			notificationIntent = new Intent(context, DummyActivity.class);	
			notificationIntent.putExtra("RunMode", "NORMAL");						//
			PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
			NotificationManager nm = (NotificationManager) context
			.getSystemService(Context.NOTIFICATION_SERVICE);
			Resources res = context.getResources();
			Builder builder = new Builder(context);
			builder.setContentIntent(contentIntent)
			.setSmallIcon(R.drawable.ic_launcher)
			.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
			.setTicker(res.getString(R.string.app_name))
			.setWhen(System.currentTimeMillis())
			.setAutoCancel(true)
			.setContentTitle(res.getString(R.string.app_name))
			.setContentText(getString(R.string.gcm_you_canceled));
			Notification n = builder.build();
			nm.notify(0, n);
		}else{		// 
			Log.e(TAG,"message:::"+message);
			notificationIntent = new Intent(context, DummyActivity.class);	
			notificationIntent.putExtra("RunMode", "NORMAL");						
			notificationIntent.putExtra("MESSAGE", message);
			PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
			NotificationManager nm = (NotificationManager) context
			.getSystemService(Context.NOTIFICATION_SERVICE);
			Resources res = context.getResources();
			Builder builder = new Builder(context);
			builder.setContentIntent(contentIntent)
			.setSmallIcon(R.drawable.ic_launcher)
			.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
			.setTicker(res.getString(R.string.app_name))
			.setWhen(System.currentTimeMillis())
			.setAutoCancel(true)
			.setContentTitle(res.getString(R.string.app_name))
			.setContentText(message);
//			.setContentText(getString(R.string.gcm_new_event));
			Notification n = builder.build();
			nm.notify(0, n);
		}
	}
	
///////////////////////////////////////////////////////////////////////////////////////////////

	/**
	 * backgroundThreadUpdateMyGCMtoServer
	 * 비동기  .   GCM 아이디 업뎃 호출  -- 서버에 gcm 아이디 업뎃
	 * @author blue
	 *
	 */
	public class backgroundThreadUpdateMyGCMtoServer extends AsyncTask<Void, Void, Void>{
		@Override protected void onPostExecute(Void result) {  
		} 
		@Override protected void onPreExecute() {  
		} 
		@Override protected Void doInBackground(Void... params) {  
			Log.d(TAG,"backgroundThreadUpdateMyGCMtoServer");
			if(myQR==null || myQR.length()<1){
				// qr 없으면 업데이트 하지 않음
			}else{			// qr 있을때에만 업데이트 
				
				// 파라미터 세팅
				MemberUser memberUserParam = new MemberUser();
				memberUserParam.setQrCode(myQR);
				memberUserParam.setRegistrationId(regIdGCM);
				// 서버 메소드 호출
				WaitNumberCustomerRest waitNumberCustomerRest = new WaitNumberCustomerRest();
				String callResult  = waitNumberCustomerRest.RestUpdateMyGCMtoServer(memberUserParam);
				// 결과 처리 
				if(callResult.equals("SUCCESS")){				//  성공
	    			Log.i(TAG, "S to update GCM ID to server");
	    			// 서버에 성공적으로 저장되면 설정에도 저장한다.
	    			saveGCMIdToPref();
	    		}else{														//  실패
	    			Log.i(TAG, "F to update GCM ID to server");
	    		}
			}
			return null; 
		}
	}
	

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	public Context returnThis(){
		return this;
	}
	
	// 진동 1
	public void vibrateOneTimes(){
		new Thread(
				new Runnable(){
					public void run(){
						try {
								Vi.vibrate(1000);
								Thread.sleep(2000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
		).start();
	}
	// 진동 3
	public void vibrateNTimes(){
		new Thread(
				new Runnable(){
					public void run(){
						try {
							for(int i=0; i<vibrateCnt; i++){
								Vi.vibrate(1000);
								Thread.sleep(2000);
							}
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
		).start();
	}
}
